#include "game3.h"
#include "ui_game3.h"
#include <QPainter>
#include <QDebug>
#include <QTimer>
#include <QMouseEvent>
#include <QPixmap>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include "menu.h"

map4 map44;
QTimer *timer4=new QTimer();
int speed4=500;
int renew=1;//强行初始化

map4::map4()
{
    int bug1x[11]={2,2,2};
    int bug1y[11]={1,2,3};
    int bug2x[11]={1,2,1,2};
    int bug2y[11]={1,1,2,2};
    int bug3x[11]={1,2,2,3};
    int bug3y[11]={2,1,3,2};
    for (int i=0;i<3;i++)
    {
        map[bug1x[i]+40][bug1y[i]+2]=1;
    }
    for (int i=0;i<4;i++)
    {
        map[bug2x[i]+40][bug2y[i]+40]=1;
    }
    for (int i=0;i<4;i++)
    {
        map[bug3x[i]+2][bug3y[i]+40]=1;
    }
}

Game3::Game3(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Game3)
{
    if (playthrough>=4)
    {
        //设置音乐
        QMediaPlaylist *musicList = new QMediaPlaylist(this);
        musicList->addMedia(QUrl("qrc:/resourse/music4.mp3"));

        QMediaPlayer *soundPlayer = new QMediaPlayer(this);
        soundPlayer->setPlaylist(musicList);
        soundPlayer->play();
        musicList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
    }
    ui->setupUi(this);
    connect(timer4,&QTimer::timeout,this,&Game3::timerUpdate);
    timer4->stop();
    ui->speedSpinBox->setValue(speed4);
    this->setAttribute(Qt::WA_DeleteOnClose);
}

Game3::~Game3()
{
    delete ui;
}

void Game3::paintEvent(QPaintEvent *)
{
    if (playthrough==4&&renew==1)
    {
        timer4->start(50);
        map44.mapclear();
        renew--;
    }
    QPainter painter(this);

    //设置网格颜色
    QPen pen(Qt::gray);
    painter.setPen(pen);

    //以label左上角为原点
    painter.translate(ui->label->x(),ui->label->y());

    //清空画布
    QBrush brush(Qt::white,Qt::SolidPattern);
    painter.setBrush(brush);
    painter.drawRect(0,0,ui->label->width()-1,ui->label->height()-1);

    //绘制网格
    for(int x=0;x<=map44.getwidthnum();x++)
    {
        painter.drawLine(x*map44.getwidth(),0,x*map44.getwidth(),map44.getheightnum()*map44.getheight());
    }
    for(int y=0;y<=map44.getheightnum();y++)
    {
        painter.drawLine(0,y*map44.getheight(),map44.getwidthnum()*map44.getwidth(),y*map44.getheight());
    }

    //绘制细胞
    brush.setColor(Qt::black);
    painter.setBrush(brush);
    for(int x=0;x<map44.getwidthnum();x++)
    {
        for(int y=0;y<map44.getheightnum();y++)
        {
            if(map44.getmap(x,y)==1)
                    painter.drawRect(x*map44.getwidth(),y*map44.getheight(),map44.getwidth(),map44.getheight());
        }
    }

    qh[1].load(":/resourse/p3.png") ;
    qh[2].load(":/resourse/p4.png") ;
    int x1=ui->p3frame->pos().x();
    int y1=ui->p3frame->pos().y();
    int x2=ui->p4frame->pos().x();
    int y2=ui->p4frame->pos().y();
    painter.drawPixmap(x1+720,y1,ui->p3frame->width(),ui->p3frame->height(),qh[1]);
    painter.drawPixmap(x2+720,y2,ui->p4frame->width(),ui->p4frame->height(),qh[2]);
    if (playthrough<=3)
    {
        ui->label_2->setStyleSheet("border:1px solid red;");
    }
    else
    {
        ui->label_5->setStyleSheet("border:1px solid red;");
    }
    painter.end();

    int t=map44.check();
    //t=1;//test
    if (t==1)
    {
        timer4->stop();
        map44.mapclear();
        this->close();
        meaningoflife *m=new meaningoflife();
        m->show();
    }

}

void Game3::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton)
    {
        QPoint point=event->pos()-ui->label->pos();
        //offset=event->pos()-ui->label->pos();
        if (playthrough<=3)
        {
            if(point.x()>=0 and point.x()<map44.getwidth()*8 and point.y()>=0 and point.y()<map44.getheight()*8)//防止超出范围
            {
                lastcellx=point.x()/map44.getwidth();
                lastcelly=point.y()/map44.getheight();
                map44.changemap(point.x()/map44.getwidth(),point.y()/map44.getheight());//改变细胞状态
                update();//重绘界面
            }
        }
        else
        {
            if(point.x()>map44.getwidth()*12 and point.x()<map44.getwidth()*36 and point.y()>map44.getwidth()*12 and point.y()<map44.getheight()*36)//防止超出范围
            {
                lastcellx=point.x()/map44.getwidth();
                lastcelly=point.y()/map44.getheight();
                map44.changemap(point.x()/map44.getwidth(),point.y()/map44.getheight());//改变细胞状态
                update();//重绘界面
            }
        }
    }
}

void Game3::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons() & Qt::LeftButton)
    {
        QPoint point=event->pos()-ui->label->pos();
        //offset=event->pos()-ui->label->pos();
        if (playthrough<=3)
        {
            if(point.x()>=0 and point.x()<map44.getwidth()*8 and point.y()>=0 and point.y()<map44.getheight()*8)//防止超出map范围
            {
                if(lastcellx!=point.x()/map44.getwidth() or lastcelly!=point.y()/map44.getheight())
                {
                    lastcellx=point.x()/map44.getwidth();
                    lastcelly=point.y()/map44.getheight();
                    map44.changemap(point.x()/map44.getwidth(),point.y()/map44.getheight());
                    update();//重绘界面
                }
            }
        }
        else
        {
            if(point.x()>map44.getwidth()*12 and point.x()<map44.getwidth()*36 and point.y()>map44.getwidth()*12 and point.y()<map44.getheight()*36)//防止超出map范围
            {
                if(lastcellx!=point.x()/map44.getwidth() or lastcelly!=point.y()/map44.getheight())
                {
                    lastcellx=point.x()/map44.getwidth();
                    lastcelly=point.y()/map44.getheight();
                    map44.changemap(point.x()/map44.getwidth(),point.y()/map44.getheight());
                    update();//重绘界面
                }
            }
        }
    }
}

void Game3::timerUpdate()
{
    map44.mapupdate();
    update();//更新界面
}

void Game3::on_startpushButton_clicked()
{
    timer4->start(speed4);
}

void Game3::on_pausepushButton_clicked()
{
    timer4->stop();
}

void Game3::on_clearpushButton_clicked()
{
    timer4->stop();
    map44.mapclear();
    update();
}

void Game3::on_speedSpinBox_valueChanged(int arg1)
{
    speed4=arg1;
    if(timer4->isActive())
        timer4->start(speed4);
}

void map4::mapupdate()
{
    int dx[8]={0,0,-1,1,-1,1,-1,1};
    int dy[8]={1,-1,0,0,1,1,-1,-1};

    memset(neighbor,0,sizeof(neighbor));//细胞清零

    //统计邻居细胞数量
    for(int x=0;x<widthnum;x++)
    {
        for(int y=0;y<heightnum;y++)
        {
            if(map[x][y]==1)
            {
                for(int i=0;i<8;i++)
                {
                        if(dx[i]+x>=0 and dx[i]+x<widthnum and dy[i]+y>=0 and dy[i]+y<heightnum) //防止越界
                        {
                            neighbor[dx[i]+x][dy[i]+y]++;
                        }
                }
                //微型宇宙
                if(playthrough>=4)
                {
                    if (x==0&&y!=0&&y!=heightnum-1)
                    {
                        neighbor[widthnum-1][y]++;
                        neighbor[widthnum-1][y+1]++;
                        neighbor[widthnum-1][y-1]++;
                    }
                    if (x==widthnum-1&&y!=0&&y!=heightnum-1)
                    {
                        neighbor[0][y]++;
                        neighbor[0][y+1]++;
                        neighbor[0][y-1]++;
                    }
                    if (y==0&&x!=0&&x!=widthnum-1)
                    {
                        neighbor[x][heightnum-1]++;
                        neighbor[x+1][heightnum-1]++;
                        neighbor[x-1][heightnum-1]++;
                    }
                    if (y==heightnum-1&&x!=0&&x!=widthnum-1)
                    {
                        neighbor[x][0]++;
                        neighbor[x+1][0]++;
                        neighbor[x-1][0]++;
                    }
                    if (x==0&&y==0)
                    {
                        neighbor[0][heightnum-1]++;
                        neighbor[1][heightnum-1]++;
                        neighbor[widthnum-1][0]++;
                        neighbor[widthnum-1][1]++;
                        neighbor[widthnum-1][heightnum-1]++;
                    }
                    if (x==widthnum-1&&y==heightnum-1)
                    {
                        neighbor[0][heightnum-1]++;
                        neighbor[0][heightnum-2]++;
                        neighbor[widthnum-1][0]++;
                        neighbor[widthnum-2][0]++;
                        neighbor[0][0]++;
                    }
                    if (x==widthnum-1&&y==0)
                    {
                        neighbor[0][0]++;
                        neighbor[0][1]++;
                        neighbor[widthnum-1][heightnum-1]++;
                        neighbor[widthnum-2][heightnum-1]++;
                        neighbor[0][heightnum-1]++;
                    }
                    if (x==0&&y==heightnum-1)
                    {
                        neighbor[0][0]++;
                        neighbor[1][0]++;
                        neighbor[widthnum-1][heightnum-1]++;
                        neighbor[widthnum-1][heightnum-2]++;
                        neighbor[widthnum-1][0]++;
                    }
                }
            }
        }
    }

    //改变细胞状态
    for(int x=0;x<widthnum;x++)
    {
        for(int y=0;y<heightnum;y++)
        {
            if(neighbor[x][y]==3)
                map[x][y]=1;
            else if(neighbor[x][y]!=2)
                map[x][y]=0;
        }
    }
}

void map4::mapclear()
{
    for(int x=0;x<widthnum;x++)
    {
        for(int y=0;y<heightnum;y++)
        {
            map[x][y]=0;
        }
    }
    if (playthrough<=3)
    {
        int bug1x[11]={2,2,2};
        int bug1y[11]={1,2,3};
        int bug2x[11]={1,2,1,2};
        int bug2y[11]={1,1,2,2};
        int bug3x[11]={1,2,2,3};
        int bug3y[11]={2,1,3,2};
        for (int i=0;i<3;i++)
        {
            map[bug1x[i]+40][bug1y[i]+2]=1;
        }
        for (int i=0;i<4;i++)
        {
            map[bug2x[i]+40][bug2y[i]+40]=1;
        }
        for (int i=0;i<4;i++)
        {
            map[bug3x[i]+2][bug3y[i]+40]=1;
        }
    }
    else
    {
        int fly1x[11]={1,1,2,3,4,4,5,5,5};
        int fly1y[11]={2,4,1,1,1,4,1,2,3};
        int fly2x[11]={1,1,2,3,3,4,4,4,4};
        int fly2y[11]={1,4,5,1,5,2,3,4,5};
        int fly3x[11]={1,1,1,1,2,2,3,4,4};
        int fly3y[11]={1,2,3,4,1,5,1,2,5};
        int fly4x[11]={1,1,1,2,2,3,4,5,5};
        int fly4y[11]={2,3,4,1,4,4,4,1,3};
        int fly5x[11]={1,1,1,2,2,3,4,5,5};
        int fly5y[11]={1,2,3,1,4,1,1,2,4};
        int fly6x[11]={1,1,2,3,3,4,4,4,4};
        int fly6y[11]={2,5,1,1,5,1,2,3,4};
        int fly7x[11]={1,1,1,1,2,2,3,4,4};
        int fly7y[11]={2,3,4,5,1,5,5,1,4};
        int fly8x[11]={1,1,2,3,4,4,5,5,5};
        int fly8y[11]={1,3,4,4,1,4,2,3,4};
        int centerx[41]={1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8};
        int centery[41]={1,2,3,4,5,6,7,8,1,2,7,8,1,3,6,8,1,4,5,8,1,4,5,8,1,3,6,8,1,2,7,8,1,2,3,4,5,6,7,8};
        for (int i=0;i<9;i++)
        {
            map[fly1x[i]+5][fly1y[i]+5]=1;
            map[fly2x[i]+37][fly2y[i]+5]=1;
            map[fly3x[i]+5][fly3y[i]+36]=1;
            map[fly4x[i]+37][fly4y[i]+37]=1;
            map[fly5x[i]+11][fly5y[i]+11]=1;
            map[fly6x[i]+31][fly6y[i]+11]=1;
            map[fly7x[i]+11][fly7y[i]+30]=1;
            map[fly8x[i]+30][fly8y[i]+31]=1;
        }
        for (int i=0;i<40;i++)
        {
            map[centerx[i]+18][centery[i]+19]=1;
        }
    }
}

int map4::check()
{
    bool t=1;
    for(int x=0;x<map44.widthnum;x++)
    {
        for(int y=0;y<map44.heightnum;y++)
        {
            if(map44.map[x][y]==1)
                t=0;
        }
    }
    if (t==1)
        return 1;
    else
        return 0;
}
